let canvas, ctx, width, height, size, lines, tick;

function line() {
  this.path = [];
  this.speed = rand(10, 20);
  this.count = randInt(10, 30);
  (this.x = width / 2), +1;
  this.y = height / 2 + 1;
  this.target = {
    x: width / 2,
    y: height / 2,
  };
  this.dist = 0;
  this.angle = 0;
  this.hue = tick / 5;
  this.life = 1;
  this.updateAngle();
  this.updateDist();
}

line.prototype.step = function (i) {
  this.x += Math.cos(this.angle) * this.speed;
  this.y += Math.sin(this.angle) * this.speed;

  this.updateDist();

  if (this.dist < this.speed) {
    this.x = this.target.x;
    this.y = this.target.y;
    this.changeTarget();
  }

  this.path.push({
    x: this.x,
    y: this.y,
  });
  if (this.path.length > this.count) {
    this.path.shift();
  }

  this.life -= 0.001;

  if (this.life <= 0) {
    this.path = null;
    lines.splice(i, 1);
  }
};

line.prototype.updateDist = function () {
  var dx = this.target.x - this.x,
    dy = this.target.y - this.y;
  this.dist = Math.sqrt(dx * dx + dy * dy);
};

line.prototype.updateAngle = function () {
  var dx = this.target.x - this.x,
    dy = this.target.y - this.y;
  this.angle = Math.atan2(dy, dx);
};

line.prototype.changeTarget = function () {
  var randStart = randInt(0, 3);
  switch (randStart) {
    case 0: // up
      this.target.y = this.y - size;
      break;
    case 1: // right
      this.target.x = this.x + size;
      break;
    case 2: // down
      this.target.y = this.y + size;
      break;
    case 3: // left
      this.target.x = this.x - size;
  }
  this.updateAngle();
};

line.prototype.draw = function (i) {
  ctx.beginPath();
  var rando = rand(0, 10);
  for (var j = 0, length = this.path.length; j < length; j++) {
    ctx[j === 0 ? 'moveTo' : 'lineTo'](
      this.path[j].x + rand(-rando, rando),
      this.path[j].y + rand(-rando, rando)
    );
  }
  ctx.strokeStyle =
    'hsla(' +
    rand(this.hue, this.hue + 30) +
    ', 80%, 55%, ' +
    this.life / 3 +
    ')';
  ctx.lineWidth = rand(0.1, 2);
  ctx.stroke();
};

function rand(min, max) {
  return Math.random() * (max - min) + min;
}

function randInt(min, max) {
  return Math.floor(min + Math.random() * (max - min + 1));
}

function init(elCanvas) {
  canvas = elCanvas;
  ctx = canvas.getContext('2d');
  size = 30;
  lines = [];
  reset();
  loop();
}

function reset() {
  width = Math.ceil(window.innerWidth / 2) * 2;
  height = Math.ceil(window.innerHeight / 2) * 2;
  tick = 0;

  lines.length = 0;
  canvas.width = width;
  canvas.height = height;
}

function create() {
  if (tick % 10 === 0) {
    lines.push(new line());
  }
}

function step() {
  var i = lines.length;
  while (i--) {
    lines[i].step(i);
  }
}

function clear() {
  ctx.globalCompositeOperation = 'destination-out';
  ctx.fillStyle = 'hsla(0, 0%, 0%, 0.1)';
  ctx.fillRect(0, 0, width, height);
  ctx.globalCompositeOperation = 'lighter';
}

function draw() {
  ctx.save();
  ctx.translate(width / 2, height / 2);
  ctx.rotate(tick * 0.001);
  var scale = 0.8 + Math.cos(tick * 0.02) * 0.2;
  ctx.scale(scale, scale);
  ctx.translate(-width / 2, -height / 2);
  var i = lines.length;
  while (i--) {
    lines[i].draw(i);
  }
  ctx.restore();
}

function loop() {
  requestAnimationFrame(loop);
  create();
  step();
  clear();
  draw();
  tick++;
}

function onresize() {
  reset();
}

let huhuiyu = {
  startAnimate(el) {
    window.addEventListener('resize', onresize);
    el.innerHTML = '';
    let elCanvas = document.createElement('canvas');
    el.appendChild(elCanvas);
    init(elCanvas);
  },
};

export default huhuiyu;
